Driver for 16550 UART interface
authorVarun Wadekar <[email protected]>
Tue, 19 May 2015 11:14:17 +0000 (16:44 +0530)
committerVarun Wadekar <[email protected]>
Fri, 29 May 2015 05:55:20 +0000 (11:25 +0530)
This patch adds driver for the 16550 UART interface. The driver is exposed
as a console, which platforms can use to dump their boot/crash logs.

Signed-off-by: Varun Wadekar <[email protected]>
Makefile
drivers/ti/uart/16550_console.S [new file with mode: 0644]
include/drivers/ti/uart/uart_16550.h [new file with mode: 0644]

index d38a28327af21b5fe708e6fbe2836bd8c4803db1..45341f8f328e862dae68e8fa2af2961d0f15c6d7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -212,6 +212,7 @@ INCLUDES            +=      -Iinclude/bl31                  \
                                -Iinclude/drivers               \
                                -Iinclude/drivers/arm           \
                                -Iinclude/drivers/io            \
+                               -Iinclude/drivers/ti/uart       \
                                -Iinclude/lib                   \
                                -Iinclude/lib/aarch64           \
                                -Iinclude/lib/cpus/aarch64      \
diff --git a/drivers/ti/uart/16550_console.S b/drivers/ti/uart/16550_console.S
new file mode 100644 (file)
index 0000000..ebb4615
--- /dev/null
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+#include <uart_16550.h>
+
+       .globl  console_core_init
+       .globl  console_core_putc
+       .globl  console_core_getc
+
+       /* -----------------------------------------------
+        * int console_core_init(unsigned long base_addr,
+        * unsigned int uart_clk, unsigned int baud_rate)
+        * Function to initialize the console without a
+        * C Runtime to print debug information. This
+        * function will be accessed by console_init and
+        * crash reporting.
+        * In: x0 - console base address
+        *     w1 - Uart clock in Hz
+        *     w2 - Baud rate
+        * Out: return 1 on success
+        * Clobber list : x1, x2, x3
+        * -----------------------------------------------
+        */
+func console_core_init
+       /* Check the input base address */
+       cbz     x0, init_fail
+       /* Check baud rate and uart clock for sanity */
+       cbz     w1, init_fail
+       cbz     w2, init_fail
+
+       /* Program the baudrate */
+       /* Divisor =  Uart clock / (16 * baudrate) */
+       lsl     w2, w2, #4
+       udiv    w2, w1, w2
+       and     w1, w2, #0xff           /* w1 = DLL */
+       lsr     w2, w2, #8
+       and     w2, w2, #0xff           /* w2 = DLLM */
+       ldr     w3, [x0, #UARTLCR]
+       orr     w3, w3, #UARTLCR_DLAB
+       str     w3, [x0, #UARTLCR]      /* enable DLL, DLLM programming */
+       str     w1, [x0, #UARTDLL]      /* program DLL */
+       str     w2, [x0, #UARTDLLM]     /* program DLLM */
+       mov     w2, #~UARTLCR_DLAB
+       and     w3, w3, w2
+       str     w3, [x0, #UARTLCR]      /* disable DLL, DLLM programming */
+
+       /* 8n1 */
+       mov     w3, #3
+       str     w3, [x0, #UARTLCR]
+       /* no interrupt */
+       mov     w3, #0
+       str     w3, [x0, #UARTIER]
+       /* enable fifo, DMA */
+       mov     w3, #(UARTFCR_FIFOEN | UARTFCR_DMAEN)
+       str     w3, [x0, #UARTFCR]
+       /* DTR + RTS */
+       mov     w3, #3
+       str     w3, [x0, #UARTMCR]
+       mov     w0, #1
+init_fail:
+       ret
+endfunc console_core_init
+
+       /* --------------------------------------------------------
+        * int console_core_putc(int c, unsigned int base_addr)
+        * Function to output a character over the console. It
+        * returns the character printed on success or -1 on error.
+        * In : w0 - character to be printed
+        *      x1 - console base address
+        * Out : return -1 on error else return character.
+        * Clobber list : x2
+        * --------------------------------------------------------
+        */
+func console_core_putc
+       /* Check the input parameter */
+       cbz     x1, putc_error
+
+       /* Prepend '\r' to '\n' */
+       cmp     w0, #0xA
+       b.ne    2f
+       /* Check if the transmit FIFO is full */
+1:     ldr     w2, [x1, #UARTLSR]
+       and     w2, w2, #(UARTLSR_TEMT | UARTLSR_THRE)
+       cmp     w2, #(UARTLSR_TEMT | UARTLSR_THRE)
+       b.ne    1b
+       mov     w2, #0xD                /* '\r' */
+       str     w2, [x1, #UARTTX]
+       ldr     w2, [x1, #UARTFCR]
+       orr     w2, w2, #UARTFCR_TXCLR
+       str     w2, [x1, #UARTFCR]
+
+       /* Check if the transmit FIFO is full */
+2:     ldr     w2, [x1, #UARTLSR]
+       and     w2, w2, #(UARTLSR_TEMT | UARTLSR_THRE)
+       cmp     w2, #(UARTLSR_TEMT | UARTLSR_THRE)
+       b.ne    2b
+       str     w0, [x1, #UARTTX]
+       ldr     w2, [x1, #UARTFCR]
+       orr     w2, w2, #UARTFCR_TXCLR
+       str     w2, [x1, #UARTFCR]
+       ret
+putc_error:
+       mov     w0, #-1
+       ret
+endfunc console_core_putc
+
+       /* ---------------------------------------------
+        * int console_core_getc(void)
+        * Function to get a character from the console.
+        * It returns the character grabbed on success
+        * or -1 on error.
+        * In : w0 - console base address
+        * Out : return -1 on error else return character.
+        * Clobber list : x0, x1
+        * ---------------------------------------------
+        */
+func console_core_getc
+       /* Check if the receive FIFO is empty */
+1:     ldr     w1, [x0, #UARTLSR]
+       tbz     w1, #UARTLSR_RDR, 1b
+       ldr     w0, [x0, #UARTRX]
+       ret
+getc_error:
+       mov     w0, #-1
+       ret
+endfunc console_core_getc
diff --git a/include/drivers/ti/uart/uart_16550.h b/include/drivers/ti/uart/uart_16550.h
new file mode 100644 (file)
index 0000000..2c814ef
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of ARM nor the names of its contributors may be used
+ * to endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __UART_16550_H__
+#define __UART_16550_H__
+
+/* UART16550 Registers */
+#define UARTTX                 0x0
+#define UARTRX                 0x0
+#define UARTDLL                        0x0
+#define UARTIER                        0x4
+#define UARTDLLM               0x4
+#define UARTIIR                        0x8
+#define UARTFCR                        0x8
+#define UARTLCR                        0xc
+#define UARTMCR                        0x10
+#define UARTLSR                        0x14
+#define UARTMSR                        0x18
+#define UARTSPR                        0x1c
+#define UARTCSR                        0x20
+#define UARTRXFIFOCFG          0x24
+#define UARTMIE                        0x28
+#define UARTVNDR               0x2c
+#define UARTASR                        0x3c
+
+/* FIFO Control Register bits */
+#define UARTFCR_FIFOMD_16450   (0 << 6)
+#define UARTFCR_FIFOMD_16550   (1 << 6)
+#define UARTFCR_RXTRIG_1       (0 << 6)
+#define UARTFCR_RXTRIG_4       (1 << 6)
+#define UARTFCR_RXTRIG_8       (2 << 6)
+#define UARTFCR_RXTRIG_16      (3 << 6)
+#define UARTFCR_TXTRIG_1       (0 << 4)
+#define UARTFCR_TXTRIG_4       (1 << 4)
+#define UARTFCR_TXTRIG_8       (2 << 4)
+#define UARTFCR_TXTRIG_16      (3 << 4)
+#define UARTFCR_DMAEN          (1 << 3)        /* Enable DMA mode */
+#define UARTFCR_TXCLR          (1 << 2)        /* Clear contents of Tx FIFO */
+#define UARTFCR_RXCLR          (1 << 1)        /* Clear contents of Rx FIFO */
+#define UARTFCR_FIFOEN         (1 << 0)        /* Enable the Tx/Rx FIFO */
+
+/* Line Control Register bits */
+#define UARTLCR_DLAB           (1 << 7)        /* Divisor Latch Access */
+#define UARTLCR_SETB           (1 << 6)        /* Set BREAK Condition */
+#define UARTLCR_SETP           (1 << 5)        /* Set Parity to LCR[4] */
+#define UARTLCR_EVEN           (1 << 4)        /* Even Parity Format */
+#define UARTLCR_PAR            (1 << 3)        /* Parity */
+#define UARTLCR_STOP           (1 << 2)        /* Stop Bit */
+#define UARTLCR_WORDSZ_5       0               /* Word Length of 5 */
+#define UARTLCR_WORDSZ_6       1               /* Word Length of 6 */
+#define UARTLCR_WORDSZ_7       2               /* Word Length of 7 */
+#define UARTLCR_WORDSZ_8       3               /* Word Length of 8 */
+
+/* Line Status Register bits */
+#define UARTLSR_RXFIFOEMT      (1 << 9)        /* Rx Fifo Empty */
+#define UARTLSR_TXFIFOFULL     (1 << 8)        /* Tx Fifo Full */
+#define UARTLSR_RXFIFOERR      (1 << 7)        /* Rx Fifo Error */
+#define UARTLSR_TEMT           (1 << 6)        /* Tx Shift Register Empty */
+#define UARTLSR_THRE           (1 << 5)        /* Tx Holding Register Empty */
+#define UARTLSR_BRK            (1 << 4)        /* Break Condition Detected */
+#define UARTLSR_FERR           (1 << 3)        /* Framing Error */
+#define UARTLSR_PERR           (1 << 3)        /* Parity Error */
+#define UARTLSR_OVRF           (1 << 2)        /* Rx Overrun Error */
+#define UARTLSR_RDR            (1 << 2)        /* Rx Data Ready */
+
+#endif /* __UART_16550_H__ */